package org.dreamwork.jasmine2.web.controls;

import org.dreamwork.jasmine2.util.StringConverter;
import org.dreamwork.jasmine2.web.IWebControl;
import org.dreamwork.jasmine2.events.EventException;
import org.dreamwork.jasmine2.engine.HttpContext;
import org.dreamwork.peony.DataBinder;

import java.util.List;
import java.util.ArrayList;
import java.io.PrintWriter;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2009-11-2
 * Time: 10:45:30
 */
public class ComboBox extends DropdownList {
    private StringBuilder client_values_array = new StringBuilder ();
    private String autoCommit = null;
    private String onChange = null;
    private String width, height;
    private String css;

    public String getCss () {
        return css;
    }

    public void setCss (String css) {
        this.css = css;
    }

    public String getOnChange () {
        return onChange;
    }

    public void setOnChange (String onChange) {
        this.onChange = onChange;
    }

    public String getWidth () {
        return width;
    }

    public void setWidth (String width) {
        this.width = width;
    }

    public String getHeight () {
        return height;
    }

    public void setHeight (String height) {
        this.height = height;
    }

    @Override
    public void init () {
        super.init ();
        htmlTagName = "div";

        page.registerStyleFile (InternalJS.class, InternalJS.COMBOBOX_DEFAULT_CSS);
        page.registerClientScriptBlock (InternalJS.class, InternalJS.COMOBBOX_JS);
//        page.registerClientScriptBlock (InternalJS.class, InternalJS.UTIL_JS);
        page.registerClientScriptBlock (InternalJS.class, InternalJS.EVENT_JS);
        page.addStartupStatement ("FixPrototypeForGecko ();");
    }

    @Override
    public void createChildControls () {
        Panel root = new Panel ();

        String id = getClientId ();
        if (StringConverter.isEmpty (id) || id.startsWith ("_auto_"))
            id = getAttribute ("clientid");
        attrs.remove ("clientid");

        if (!StringConverter.isEmpty (css)) {
            StringBuilder builder = new StringBuilder ("<style>#").append (id).append ("-container.jasmine-combobox {").append (css).append ("}\r\n");
            builder.append ("#").append (id).append ("-container.jasmine-combobox-hover {").append (css).append ("}</style>\r\n");
            root.addControl (new Literal (builder));
        } else {

            List<String> css = new ArrayList<String> ();
            if (!StringConverter.isEmpty (width)) {
                if (width.toLowerCase ().endsWith ("px")) css.add ("width:" + width + ";");
                else css.add ("width:" + width + "px;");
            }

            if (!StringConverter.isEmpty (height)) {
                if (height.toLowerCase ().endsWith ("px")) css.add ("height:" + height + ";");
                else css.add ("height:" + height + "px;");
            }

            if (css.size () > 0) {
                StringBuilder aa = new StringBuilder ("#").append (id).append ("-container.jasmine-combobox {");
                StringBuilder bb = new StringBuilder ("#").append (id).append ("-container.jasmine-combobox-hover {");
                for (String s : css) {
                    aa.append (s);
                    bb.append (s);
                }
                String s = "<style>" + aa + "}\r\n" + bb + "}</style>\r\n";
                root.addControl (new Literal (s));
            }
        }

        Panel panel = new Panel ();


        if (!StringConverter.isEmpty (id) && !id.startsWith ("_auto_"))
            panel.setId (id + "-container");
        root.addControl (panel);

        Panel label = new Panel ();
        label.setId (id + "-label");
        label.setAttribute ("class", "jasmine-list-label");
        panel.addControl (label);

        panel.setAttribute ("class", "jasmine-combobox");
        panel.setAttribute ("onclick", "_jasmine_combox_click('" + id + "')");
        panel.setAttribute ("onmouseover", "this.className='jasmine-combobox-hover'");
        panel.setAttribute ("onmouseout", "this.className='jasmine-combobox'");

        Hidden hidden = new Hidden ();
        hidden.setAttribute ("type", "hidden");
        hidden.setId (id);
        root.addControl (hidden);

        if (runAtServer && autoPostback) {
            page.registerClientScriptBlock (InternalJS.class, InternalJS.ON_CLICK_JS);
            hidden.setAttribute ("onchange", "__client_stub (this, 'change', '" + KEY_SELECTED_VALUE + "')");
        } else if (!StringConverter.isEmpty (onChange)) {
            hidden.setAttribute ("onchange", onChange);
        }

        panel = new Panel ();
        panel.setId (id + "-list");
        panel.setAttribute ("class", "jasmine-hidden-list-body");
        root.addControl (panel);

        int offset = childControls.count ();
        List<Panel> pis = new ArrayList<Panel> ();

        int index = 0;
        for (int i = 0; i < offset; i++) {
            ListItem item = (ListItem) childControls.get (i);
            Panel pi = createPanelItem (panel, id, i, item.getText (), item.getValue ());
            if (item.isSelected ()) {
                selectedIndex = i;
                selectedValue = item.getValue ();
                pis.add (pi);
            } else {
                if (selectedIndex != -1) {
                    if (selectedIndex == i) {
                        item.setSelected (true);
                        selectedValue = item.getValue ();
                        pis.add (pi);
                    }
                } else if (selectedValue != null) {
                    if (selectedValue.equals (item.getValue ())) {
                        selectedIndex = i;
                        item.setSelected (true);
                        pis.add (pi);
                    }
                }
            }
            index = i;
        }

        if (data != null) for (int i = 0; i < data.size (); i++) {
            ListItem item = new ListItem ();
            item.setId (this.id + '_' + (i + offset));
            Object container = data.get (i);
            Object value = DataBinder.eval (container, valueField);
            Object text = DataBinder.eval (container, textField);
            item.setValue (StringConverter.contvertToString (value));
            item.setText (StringConverter.contvertToString (text));

            Panel pi = this.createPanelItem (panel, id, index + i, item.getText (), item.getValue ());

            if ((i + offset) == selectedIndex) {
                pis.add (pi);
                selectedValue = value;
            } else if (StringConverter.stringEquals (selectedValue, value)) {
                selectedIndex = i + offset;
                pis.add (pi);
            }
        }

        Panel pi = null;
        if (pis.size () > 0) {
            pi = pis.get (pis.size () - 1);
        } else if (panel.getChildControls ().count () > 0) {
            pi = (Panel) panel.getChildControls ().get (0);
        }
        if (pi != null) {
            pi.setAttribute ("class", "jasmine-hightlight");
            label.addControl (new Literal (((IWebControl) pi.getChildControls ().get (0)).getInnerText ()));
            hidden.setText (StringConverter.contvertToString (selectedValue));
        }

        this.childControls.clear ();
        for (int i = 0; i < root.getChildControls ().count (); i++) {
            IWebControl c = (IWebControl) root.getChildControls ().get (i);
            addControl (c);
        }

        page.addStartupStatement ("_list_values['" + id + "'] = {\"values\":[" + client_values_array + "], \"selectedIndex\":" + +selectedIndex + "};\r\n");
        page.addStartupStatement ("_comobbox_controls.push ('" + id + "');\r\n");


        if (this.viewStateEnabled) {
            stateManager.put (KEY_SELECTED_INDEX, new Integer (selectedIndex));
            stateManager.put (KEY_SELECTED_VALUE, selectedValue);
        }
    }

    public void addControl (IWebControl control) {
        checkControl (control);

        if (page == null) {
            context = HttpContext.current ();
            page = context.getPage ();
        }
        String id = control.getId ();
        if (id == null) {
            id = "_auto_control_" + StringConverter.generateUUID ();
            control.setId (id);
        }
        childControls.add (id, control);
        if (!(control instanceof UserControl) && control.getPage () != page) {
            control.setPage (page);
        }
        if (isInited ()) control.init ();
        control.setParent (this);
    }

    private Panel createPanelItem (Panel panel, String id, int i, String text, String value) {
        Panel pi = new Panel ();
        pi.setId (id + "-item-" + i);
        pi.setAttribute ("onmouseover", "_jasmine_hightlight(this)");
        pi.setAttribute ("onclick", "_jasmine_selectItem(this)");
        panel.addControl (pi);
        pi.addControl (new Literal (text));
        if (client_values_array.length () > 0) client_values_array.append (", ");
        client_values_array.append ("'").append (value).append ("'");
        return pi;
    }

    @Override
    public void render (PrintWriter writer) throws IOException, EventException {
        for (int i = 0; i < childControls.count (); i++) {
            IWebControl control = childControls.getControl (i);
            control.render (writer);
        }
    }
}